home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Magazine / C_Tutorial / Part-6 / asl1.c < prev    next >
C/C++ Source or Header  |  1997-10-27  |  20KB  |  767 lines

  1. #include "iff.h"
  2.  
  3. #include<exec/libraries.h>
  4. #include<intuition/intuition.h>
  5. #include<utility/tagitem.h>
  6. #include<graphics/text.h>
  7. #include<graphics/rastport.h>
  8. #include<intuition/screens.h>
  9. #include<libraries/gadtools.h>
  10. #include<libraries/asl.h>
  11. #include<exec/memory.h>
  12.  
  13. #include<string.h>
  14. #include<stdio.h>
  15.  
  16. #include<clib/exec_protos.h>
  17. #include<clib/graphics_protos.h>
  18. #include<clib/intuition_protos.h>
  19. #include<clib/gadtools_protos.h>
  20. #include<clib/asl_protos.h>
  21. #include<clib/dos_protos.h>
  22.  
  23. /* The library base global variables */
  24. /* (The different style of opening libraries requires these to be initialised to NULL) */
  25. struct Library* GfxBase = NULL;
  26. struct Library* IntuitionBase = NULL;
  27. struct Library* GadToolsBase = NULL;
  28. struct Library* AslBase = NULL;
  29. struct Library* DosBase = NULL;
  30. struct Library* IFFBase = NULL;
  31.  
  32. /* The global handle on the palette gadget */
  33. struct Gadget* palgad = NULL;
  34. /* Global record of foreground pen */
  35. UBYTE pen;
  36. /* Global records of our windows */
  37. struct Window* drawwin = NULL;
  38. struct Window* toolwin = NULL;
  39. /* Global record of title bar height */
  40. int offtop;
  41. /* Global record of our menu strip */
  42. struct Menu* menustrip = NULL;
  43. /* Global record of the screen's visual information */
  44. APTR vinfo = NULL;
  45. /* Initialised structure declaration: describes 8pt Topaz font */
  46. struct TextAttr topazFont = { "topaz.font", 8, 0, 0, };
  47. /* Global record of our gadget list */
  48. struct Gadget* glist = NULL;
  49. /* Global record of our screen */
  50. struct Screen* scr = NULL;
  51. /* Global flag for whether the tool window should be open */
  52. int opentw = TRUE;
  53. /* Global handles for our requesters */
  54. struct FileRequester* loadreq = NULL;
  55. struct FileRequester* savereq = NULL;
  56. /* Global handle for our bitmap */
  57. struct BitMap* bitmap = NULL;
  58.  
  59. /* Need to give prototypes for our functions */
  60. int  createAll();
  61. void freeAll();
  62. int  openLibs();
  63. void closeLibs();
  64. int  openScr();
  65. void closeScr();
  66. int  createMenuStrip();
  67. void freeMenuStrip();
  68. int  openToolWin();
  69. void closeToolWin();
  70. int  openDrawWin();
  71. void closeDrawWin();
  72. int  createGadgets();
  73. void freeGadgets();
  74. void handleIDCMP();
  75. int  checkToolWin();
  76. void setFgPen(int);
  77. void doGadgetUp(struct IntuiMessage*);
  78. int  doMenuPick(struct IntuiMessage*);
  79. void freeReqs();
  80. void load();
  81. void save();
  82. int  createBitmap();
  83. void freeBitmap();
  84.  
  85. /* Some constants for the position and size of our gadget */
  86. #define MYBUT_LEFT        (10)
  87. #define MYBUT_TOP            (5)
  88. #define MYBUT_WIDTH        (80)
  89. #define MYBUT_HEIGHT    (12)
  90. #define MYBUT_TEXT        "Next Pen"
  91. #define MYBUT_ID            (0)
  92.  
  93. #define MYPAL_LEFT        (170)
  94. #define MYPAL_TOP            (1)
  95. #define MYPAL_WIDTH        (109)
  96. #define MYPAL_HEIGHT    (19)
  97. #define MYPAL_TEXT        "Colour:"
  98. #define MYPAL_ID            (1)
  99. #define MYPAL_DEPTH        (4)
  100.  
  101. /* The top gap required around the gadgets */
  102. #define MYTOPGAP      (21)
  103.  
  104. /* The initial pen colour */
  105. #define MYINITPEN            (1)
  106.  
  107. /* The size of our filename string */
  108. #define MAXFILENAME        (300)
  109.  
  110. /* The start of the program */
  111. void main()
  112. {
  113.     /* Use a different style of opening libraries... */
  114.     if(createAll())
  115.     {
  116.         /* Now do the real work */
  117.         handleIDCMP();
  118.     }
  119.     /* Matched call to close libraries */
  120.     freeAll();
  121. }
  122.  
  123. int createAll()
  124. {
  125.     return openLibs() && openScr() && createBitmap() && createMenuStrip() && createGadgets() && openToolWin() && openDrawWin();
  126. }
  127.  
  128. void freeAll()
  129. {
  130.     freeReqs();
  131.     closeDrawWin();
  132.     closeToolWin();
  133.     freeGadgets();
  134.     freeMenuStrip();
  135.     freeBitmap();
  136.     closeScr();
  137.     closeLibs();
  138. }
  139.  
  140. /* Try to open all the libraries -- return TRUE on success */
  141. int openLibs()
  142. {
  143.     if((GfxBase = OpenLibrary("graphics.library",37)) == NULL)
  144.     {
  145.         printf("Error: could not open graphics.library\n");
  146.         return FALSE;
  147.     }
  148.     if((IntuitionBase = OpenLibrary("intuition.library",37)) == NULL)
  149.     {
  150.         printf("Error: could not open intuition.library\n");
  151.         return FALSE;
  152.     }
  153.     if((GadToolsBase = OpenLibrary("gadtools.library",37)) == NULL)
  154.     {
  155.         printf("Error: could not open gadtools.library\n");
  156.         return FALSE;
  157.     }
  158.     if((AslBase = OpenLibrary("asl.library",37)) == NULL)
  159.     {
  160.         printf("Error: could not open asl.library\n");
  161.         return FALSE;
  162.     }
  163.     if((DosBase = OpenLibrary("dos.library",37)) == NULL)
  164.     {
  165.         printf("Error: could not open dos.library\n");
  166.         return FALSE;
  167.     }
  168.     if((IFFBase = OpenLibrary("iff.library",23)) == NULL)
  169.     {
  170.         printf("Error: could not open iff.library\n");
  171.         return FALSE;
  172.     }
  173.   return TRUE;
  174. }
  175.  
  176. /* Close any open library */
  177. void closeLibs()
  178. {
  179.     if(IFFBase)
  180.         CloseLibrary(IFFBase);
  181.     if(DosBase)
  182.         CloseLibrary(DosBase);
  183.     if(AslBase)
  184.         CloseLibrary(AslBase);
  185.     if(GadToolsBase)
  186.         CloseLibrary(GadToolsBase);
  187.     if(IntuitionBase)
  188.         CloseLibrary(IntuitionBase);
  189.     if(GfxBase)
  190.         CloseLibrary(GfxBase);
  191. }
  192.  
  193. /* Open screen and setup GadTools stuff */
  194. int openScr()
  195. {
  196.     UWORD pens[] = { ~0 };
  197.     /* Try to open a new screen with 16 colours (four bitplanes deep) */
  198.     if(scr = OpenScreenTags(NULL,
  199.                                                     SA_Depth,    4,
  200.                                                     /* Enable 3D look by specifying SA_Pens */
  201.                                                     SA_Pens,    pens,
  202.                                                     SA_Title,    "Hello World Painter",
  203.                                                     TAG_DONE))
  204.     {
  205.         /* Get the visual info so GadTools can render the gadgets nicely */
  206.         if(vinfo = GetVisualInfo(scr, TAG_DONE))
  207.             /* Succeeded */
  208.             return TRUE;
  209.         else
  210.             printf("Error: could not get visual info\n");
  211.     }
  212.     else
  213.         printf("Error: could not create screen\n");
  214.     /* Failed */
  215.     return FALSE;
  216. }
  217.  
  218. void closeScr()
  219. {
  220.     if(vinfo)
  221.     {
  222.         FreeVisualInfo(vinfo);
  223.         vinfo = NULL;
  224.     }
  225.     if(scr)
  226.     {
  227.         CloseScreen(scr);
  228.         scr = NULL;
  229.     }
  230. }
  231.  
  232. /* Create the menu strip, using GadTools menu functions */
  233. int createMenuStrip()
  234. {
  235.     /* The description of our menus */
  236.     struct NewMenu mymenu[] =
  237.     {
  238.         { NM_TITLE, "Project",            0,        0, 0, 0,},
  239.         {  NM_ITEM,        "Load",                "L",    0, 0, 0,},
  240.         {  NM_ITEM,        "Save",                "S",    0, 0, 0,},
  241.         {  NM_ITEM,        NM_BARLABEL,    0,        0, 0, 0,},
  242.         {  NM_ITEM,        "Quit",                "Q",    0, 0, 0,},
  243.         { NM_TITLE, "Pen",                    0,        0, 0, 0,},
  244.         {  NM_ITEM,        "Next",                "N",    0, 0, 0,},
  245.         {  NM_ITEM,        "Prev",                "P",    0, 0, 0,},
  246.         {  NM_ITEM,        NM_BARLABEL,    0,        0, 0, 0,},
  247.         {  NM_ITEM,        "Reset",            "R",    0, 0, 0,},
  248.         { NM_TITLE, "Tools",                0,        0, 0, 0,},
  249.         {  NM_ITEM,        "Screen Bar",    "C",    CHECKIT | MENUTOGGLE | CHECKED, 0, 0,},
  250.         {  NM_ITEM,        "Tool Bar",        "T",    CHECKIT | MENUTOGGLE | CHECKED, 0, 0,},
  251.         {   NM_END, NULL,                        0,        0, 0, 0,},
  252.     };
  253.     if (menustrip = CreateMenus(mymenu, TAG_END))
  254.     {
  255.         if (LayoutMenus(menustrip, vinfo, TAG_END))
  256.             /* Succeeded */
  257.             return TRUE;
  258.         else
  259.             printf("Error: could not layout menus\n");
  260.     }
  261.     else
  262.         printf("Error: could not create menu strip\n");
  263.     /* Failed */
  264.     return FALSE;
  265. }
  266.  
  267. void freeMenuStrip()
  268. {
  269.     if(menustrip)
  270.     {
  271.         FreeMenus(menustrip);
  272.         menustrip = NULL;
  273.     }
  274. }
  275.  
  276. /* Actually open the windows, in the normal way */
  277. int openToolWin()
  278. {
  279.     /* Extra protection -- only open if not already open */
  280.     if(toolwin == NULL)
  281.     {
  282.         /* The minimal height of our tool window */
  283.         int h = MYTOPGAP + offtop + scr->WBorBottom;
  284.         /* Open our tool window */
  285.         if(toolwin = OpenWindowTags(NULL,
  286.                                                                 WA_Left,                    0,
  287.                                                                 WA_Top,                        scr->Height - h,
  288.                                                                 /* Make the window sit in the bottom of the screen */
  289.                                                                 WA_Width,                    scr->Width,
  290.                                                                 WA_Height,                h,
  291.                                                                 WA_Flags,                    WFLG_CLOSEGADGET | WFLG_DRAGBAR,
  292.                                                                 WA_IDCMP,                    IDCMP_CLOSEWINDOW | BUTTONIDCMP | IDCMP_REFRESHWINDOW | IDCMP_MENUPICK,
  293.                                                                 WA_Gadgets,                glist,
  294.                                                                 WA_CustomScreen,    scr,
  295.                                                                 WA_Title,                    "Tools",
  296.                                                                 TAG_DONE,                    0))
  297.         {
  298.             /* Attach menu strip to tool window, as well */
  299.             if(SetMenuStrip(toolwin, menustrip))
  300.             {
  301.                 /* Let GadTools refresh its bits of the tool window */
  302.                 GT_RefreshWindow(toolwin, NULL);
  303.                 return TRUE;
  304.             }
  305.             else
  306.                 printf("Error: could not attach menus to tool window\n");
  307.         }
  308.         else
  309.             printf("Error: could not open tool window\n");
  310.     }
  311.     else
  312.         printf("Warning: tool window already open\n");
  313.     return FALSE;
  314. }
  315.  
  316. void closeToolWin()
  317. {
  318.     if(toolwin)
  319.     {
  320.         ClearMenuStrip(toolwin);
  321.         CloseWindow(toolwin);
  322.         toolwin = NULL;
  323.     }
  324. }
  325.  
  326. int openDrawWin()
  327. {
  328.     /* Open our drawing window */
  329.     if(drawwin = OpenWindowTags(NULL,
  330.                                                             WA_Left,                    0,
  331.                                                             WA_Top,                        0,
  332.                                                             /* Make the window the same size as the screen */
  333.                                                             WA_Width,                    scr->Width,
  334.                                                             WA_Height,                scr->Height,
  335.                                                             WA_Flags,                    WFLG_BACKDROP | WFLG_BORDERLESS | WFLG_REPORTMOUSE | WFLG_SUPER_BITMAP,
  336.                                                             WA_IDCMP,                    IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_MENUPICK,
  337.                                                             WA_CustomScreen,    scr,
  338.                                                             WA_SuperBitMap,        bitmap,
  339.                                                             TAG_DONE,                    0))
  340.     {
  341.         /* Clear our window, since our new bitmap may not be cleared already */
  342.         SetRast(drawwin->RPort, 0);
  343.         /* Set the drawing mode to draw only the foreground of text, not the background */
  344.         SetDrMd(drawwin->RPort, JAM1);
  345.         /* Attach menu strip to drawing window */
  346.         if(SetMenuStrip(drawwin, menustrip))
  347.             return TRUE;
  348.         else
  349.             printf("Error: could not attach menus to drawing window\n");
  350.     }
  351.     else
  352.         printf("Error: could not open drawing window\n");
  353.     return FALSE;
  354. }
  355.  
  356. void closeDrawWin()
  357. {
  358.     if(drawwin)
  359.     {
  360.         ClearMenuStrip(drawwin);
  361.         CloseWindow(drawwin);
  362.         drawwin = NULL;
  363.     }
  364. }
  365.  
  366. int createGadgets()
  367. {
  368.     struct Gadget* gad;
  369.     int offleft;
  370.     struct NewGadget newgad;
  371.     /* Start a GadTools gadget list */
  372.     gad = CreateContext(&glist);
  373.     /* The offsets of our window borders */
  374.     offleft = scr->WBorLeft;
  375.     offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
  376.  
  377.     /* Setup our first gadget */
  378.     newgad.ng_TextAttr         = &topazFont;
  379.     newgad.ng_VisualInfo     = vinfo;
  380.     newgad.ng_LeftEdge         = MYBUT_LEFT + offleft;
  381.     newgad.ng_TopEdge         = MYBUT_TOP + offtop;
  382.     newgad.ng_Width             = MYBUT_WIDTH;
  383.     newgad.ng_Height             = MYBUT_HEIGHT;
  384.     newgad.ng_GadgetText    = MYBUT_TEXT;
  385.     newgad.ng_GadgetID        = MYBUT_ID;
  386.     newgad.ng_Flags                = 0;
  387.     /* Now create it and add it to our list */
  388.     gad = CreateGadget(BUTTON_KIND, gad, &newgad, TAG_END);
  389.  
  390.     /* Setup our second gadget */
  391.     /* (We can reuse newgad, and just change the different bits) */
  392.     newgad.ng_LeftEdge         = MYPAL_LEFT + offleft;
  393.     newgad.ng_TopEdge         = MYPAL_TOP + offtop;
  394.     newgad.ng_Width             = MYPAL_WIDTH;
  395.     newgad.ng_Height             = MYPAL_HEIGHT;
  396.     newgad.ng_GadgetText    = MYPAL_TEXT;
  397.     newgad.ng_GadgetID        = MYPAL_ID;
  398.     newgad.ng_Flags                = 0;
  399.     /* Now create it and add it to our list */
  400.     gad = CreateGadget(    PALETTE_KIND, gad, &newgad,
  401.                                             /* Initially selected pen */
  402.                                             GTPA_Color, MYINITPEN,
  403.                                             /* Depth: 2 to the power MYPAL_DEPTH colours */
  404.                                             GTPA_Depth, MYPAL_DEPTH,
  405.                                             /* Gadget will indicate selection */
  406.                                             GTPA_IndicatorWidth, 16,
  407.                                             TAG_DONE);
  408.  
  409.     /* Remember gadget pointer so we can affect it in message handler */
  410.     palgad = gad;
  411.     /* Success if we managed final allocation */
  412.     return (gad != NULL);
  413. }
  414.  
  415. void freeGadgets()
  416. {
  417.     if(glist)
  418.     {
  419.         FreeGadgets(glist);
  420.         glist = NULL;
  421.         /* Reset palgad pointer, too */
  422.         palgad = NULL;
  423.     }
  424. }
  425.  
  426. /* Our message handling code */
  427. void handleIDCMP()
  428. {
  429.     char* text = "Hello World!";
  430.     int going = TRUE;
  431.     int drawing = FALSE;
  432.     ULONG drawsig, toolsig, gotsig;
  433.     drawsig = 1 << drawwin->UserPort->mp_SigBit;
  434.     setFgPen(MYINITPEN);
  435.     while(going)
  436.     {
  437.         struct IntuiMessage* intuimsg;
  438.         /* Only include tool window signal mask if window is open */
  439.         toolsig = opentw ? 1 << toolwin->UserPort->mp_SigBit : 0;
  440.         /* Wait for messages to arrive */
  441.         gotsig = Wait(drawsig | toolsig);
  442.         /* Messages have arrived: loop through all of them */
  443.         /* Check messages from the drawing window first */
  444.         if(gotsig & drawsig)
  445.         {
  446.             while(intuimsg = GT_GetIMsg(drawwin->UserPort))
  447.             {
  448.                 /* Act on this message... */
  449.                 switch(intuimsg->Class)
  450.                 {
  451.                 case IDCMP_MOUSEBUTTONS:
  452.                     switch(intuimsg->Code)
  453.                     {
  454.                     case SELECTDOWN:
  455.                         drawing = TRUE;
  456.                         break;
  457.                     case SELECTUP:
  458.                         drawing = FALSE;
  459.                         break;
  460.                     }
  461.                     /* break; omitted so we draw on click, too */
  462.                 case IDCMP_MOUSEMOVE:
  463.                     if(drawing)
  464.                     {
  465.                         Move(drawwin->RPort, intuimsg->MouseX, intuimsg->MouseY);
  466.                         Text(drawwin->RPort, text, strlen(text));
  467.                     }
  468.                     break;
  469.                 case IDCMP_MENUPICK:
  470.                     going = doMenuPick(intuimsg);
  471.                     break;
  472.                 }
  473.                 /* Reply when finished with message */
  474.                 GT_ReplyIMsg(intuimsg);
  475.             }
  476.         }
  477.         /* Now check messages from the tool window */
  478.         if(going && (gotsig & toolsig))
  479.         {
  480.             while(intuimsg = GT_GetIMsg(toolwin->UserPort))
  481.             {
  482.                 /* Act on this message... */
  483.                 switch(intuimsg->Class)
  484.                 {
  485.                 case IDCMP_CLOSEWINDOW:
  486.                     {
  487.                         struct MenuItem* item;
  488.                         opentw = FALSE;
  489.                         /* Unset menu check mark */
  490.                         /* First, remove menu strip from windows */
  491.                         ClearMenuStrip(drawwin);
  492.                         ClearMenuStrip(toolwin);
  493.                         /* Menu 2, Item 1 is Tool Bar */
  494.                         item = ItemAddress(menustrip, FULLMENUNUM(2,1,0));
  495.                         /* Unset CHECKED flag */
  496.                         item->Flags &= ~CHECKED;
  497.                         /* Reattach menu strip to windows */
  498.                         ResetMenuStrip(toolwin,menustrip);
  499.                         ResetMenuStrip(drawwin,menustrip);
  500.                         break;
  501.                     }
  502.                 case IDCMP_REFRESHWINDOW:
  503.                     /* You *MUST* remember to ask for and handle these refresh messages */
  504.                     GT_BeginRefresh(toolwin);
  505.                     GT_EndRefresh(toolwin, TRUE);
  506.                     break;
  507.                 case IDCMP_GADGETUP:
  508.                     doGadgetUp(intuimsg);
  509.                     break;
  510.                 case IDCMP_MENUPICK:
  511.                     going = doMenuPick(intuimsg);
  512.                     break;
  513.                 }
  514.                 /* Reply when finished with message */
  515.                 GT_ReplyIMsg(intuimsg);
  516.             }
  517.         }
  518.         /* Check tool window if still going */
  519.         if(going)
  520.             going = checkToolWin();
  521.     }
  522. }
  523.  
  524. /* Check whether tool window should be opened or closed */
  525. int checkToolWin()
  526. {
  527.     if(toolwin)
  528.     {
  529.         if(!opentw)
  530.             closeToolWin();
  531.     }
  532.     else
  533.     {
  534.         if(opentw && !openToolWin())
  535.              return FALSE;  /* Error! Re-open failed */
  536.     }
  537.     return TRUE;
  538. }
  539.  
  540. /* Set foreground pen of drawing window */
  541. void setFgPen(int value)
  542. {
  543.     /* Wrap when reached the end of the palette gadget's colours */
  544.     pen = value % (1<<MYPAL_DEPTH);
  545.     /* Only set pen if window is open */
  546.     if(drawwin)
  547.         SetAPen(drawwin->RPort, pen);
  548.     /* If the palette gadget has been made, update it with new pen value */
  549.     if(palgad)
  550.         GT_SetGadgetAttrs(palgad, toolwin, NULL, GTPA_Color, pen, TAG_DONE);
  551. }
  552.  
  553. /* Process IDCMP_GADGETUP event */
  554. void doGadgetUp(struct IntuiMessage* intuimsg)
  555. {
  556.     struct Gadget* gad = (struct Gadget*)(intuimsg->IAddress);
  557.     switch(gad->GadgetID)
  558.     {
  559.     case MYBUT_ID:
  560.         /* Our button was clicked!  Set foreground to next pen colour */
  561.         setFgPen(pen+1);
  562.         break;
  563.     case MYPAL_ID:
  564.         /* Our palette gadget was clicked!  Set foreground to gadget colour */
  565.         setFgPen(intuimsg->Code);
  566.         break;
  567.     }
  568. }
  569.  
  570. /* Process IDCMP_MENUPICK event */
  571. int doMenuPick(struct IntuiMessage* intuimsg)
  572. {
  573.     UWORD menuCode, menuNumber, itemNumber;
  574.     /* Loop over all the menu selections in the menu code */
  575.     struct MenuItem* item;
  576.     for(menuCode = intuimsg->Code;
  577.             menuCode != MENUNULL;
  578.             menuCode = item->NextSelect)
  579.     {
  580.         item = ItemAddress(menustrip, menuCode);
  581.         /* Extract the menu number and menu item number from the menu code */
  582.         menuNumber = MENUNUM(menuCode);
  583.         itemNumber = ITEMNUM(menuCode);
  584.         /* Now decide what to do based on what menu item was selected */
  585.         switch(menuNumber)
  586.         {
  587.         case 0:  /* Project menu */
  588.             /* Only one item: Quit */
  589.             switch(itemNumber)
  590.             {
  591.             case 0:  /* Load */
  592.                 load();
  593.                 break;
  594.             case 1:  /* Save */
  595.                 save();
  596.                 break;
  597.             case 3:  /* Quit (item 2 is the bar!) */
  598.                 return FALSE;
  599.             }
  600.             break;
  601.         case 1:  /* Pen menu */
  602.             switch(itemNumber)
  603.             {
  604.             case 0:  /* Next */
  605.                 setFgPen(pen+1);
  606.                 break;
  607.             case 1:  /* Prev */
  608.                 setFgPen(pen-1);
  609.                 break;
  610.             case 3:  /* Reset (item 2 is the bar!) */
  611.                 setFgPen(MYINITPEN);
  612.                 break;
  613.             }
  614.             break;
  615.         case 2:  /* Tools menu */
  616.             switch(itemNumber)
  617.             {
  618.             case 0:  /* Screen Bar */
  619.                 ShowTitle(scr, item->Flags & CHECKED);
  620.                 break;
  621.             case 1:  /* Tool Bar */
  622.                 /* Set state to indicate whether the tool window should be open */
  623.                 opentw = (item->Flags & CHECKED);
  624.                 break;
  625.             }
  626.         }
  627.     }
  628.     /* Keep going */
  629.     return TRUE;
  630. }
  631.  
  632. /* Open an ASL load file requester */
  633. void load()
  634. {
  635.     /* Allocate the requester if we haven't already */
  636.     if(loadreq == NULL)
  637.         loadreq = (struct FileRequester*)AllocAslRequest(ASL_FileRequest,NULL);
  638.     if(loadreq)
  639.     {
  640.         if(AslRequestTags(loadreq,
  641.                                             ASLFR_TitleText,            "Load File",
  642.                                             ASLFR_Window,                    drawwin,
  643.                                             ASLFR_Flags1,                    FRF_DOPATTERNS,
  644.                                             ASLFR_InitialPattern,    "#?.iff",
  645.                                             TAG_DONE))
  646.         {
  647.             char filename[MAXFILENAME];
  648.             /* Create complete filename from ASL's dir and file */
  649.             strcpy(filename, loadreq->rf_Dir);
  650.             if(AddPart(filename, loadreq->rf_File, MAXFILENAME))
  651.             {
  652.                 IFFL_HANDLE handle;
  653.                 /* Try to open the IFF file */
  654.                 if(handle = IFFL_OpenIFF(filename, IFFL_MODE_READ))
  655.                 {
  656.                     LONG  count;
  657.                     UWORD colortable[256];
  658.                     /* Get colour information and change screen colours */
  659.                     count = IFFL_GetColorTab(handle, colortable);
  660.                     LoadRGB4(&(scr->ViewPort), colortable, count);
  661.                     /* If we can load the picture, update window's display */
  662.                     if(IFFL_DecodePic(handle, bitmap))
  663.                         CopySBitMap(drawwin->WLayer);
  664.                     else
  665.                         printf("Error: could not decode IFF picture\n");
  666.                     IFFL_CloseIFF(handle);
  667.                 }
  668.                 else
  669.                     printf("Error: could not open IFF file\n");
  670.             }
  671.             else
  672.                 printf("Error: could not make filename\n");
  673.         }
  674.         /* else: requester was cancelled */
  675.     }
  676.     else
  677.         printf("Error: could not allocate ASL (load) file request\n");
  678. }
  679.  
  680. /* Open an ASL save file requester */
  681. void save()
  682. {
  683.     /* Another way of saying "allocate if we haven't already" */
  684.     if(savereq || (savereq = (struct FileRequester*)AllocAslRequest(ASL_FileRequest,NULL)))
  685.     {
  686.         if(AslRequestTags(savereq,
  687.                                             ASLFR_TitleText,            "Save File",
  688.                                             ASLFR_Window,                    drawwin,
  689.                                             ASLFR_Flags1,                    FRF_DOPATTERNS | FRF_DOSAVEMODE,
  690.                                             ASLFR_InitialPattern,    "#?.iff",
  691.                                             ASLFR_InitialFile,        "picture.iff",
  692.                                             TAG_DONE))
  693.         {
  694.             char filename[MAXFILENAME];
  695.             /* Create complete filename from ASL's dir and file */
  696.             strcpy(filename, savereq->rf_Dir);
  697.             if(AddPart(filename, savereq->rf_File, MAXFILENAME))
  698.             {
  699.                 /* Make sure our bitmap is the same as the display */
  700.                 SyncSBitMap(drawwin->WLayer);
  701.                 /* Try saving our bitmap, using the screen's colours */
  702.                 if(IFFL_SaveBitMap(filename, bitmap,
  703.                                                     scr->ViewPort.ColorMap->ColorTable,
  704.                                                     IFFL_COMPR_BYTERUN1) == 0)
  705.                     printf("Error: could not write IFF picture\n");
  706.             }
  707.             else
  708.                 printf("Error: could not make filename\n");
  709.         }
  710.         /* else: requester was cancelled */
  711.     }
  712.     else
  713.         printf("Error: could not allocate ASL (save) file request\n");
  714. }
  715.  
  716. /* Free any requesters that may have been allocated */
  717. void freeReqs()
  718. {
  719.     if(loadreq)
  720.     {
  721.         FreeAslRequest(loadreq);
  722.         loadreq = NULL;
  723.     }
  724.     if(savereq)
  725.     {
  726.         FreeAslRequest(savereq);
  727.         savereq = NULL;
  728.     }
  729. }
  730.  
  731. int createBitmap()
  732. {
  733.     /* The MEMF_CLEAR flag is vital, since it zeroes the allocated memory. */
  734.     /* Thus the pointers in the bitmap will be NULL, if we don't manage to */
  735.     /* allocate them properly. */
  736.     if(bitmap = AllocMem(sizeof(struct BitMap), MEMF_PUBLIC | MEMF_CLEAR))
  737.     {
  738.         int plane;
  739.         InitBitMap(bitmap, scr->BitMap.Depth, scr->Width, scr->Height);
  740.         for(plane = 0; plane < scr->BitMap.Depth; plane++)
  741.         {
  742.             bitmap->Planes[plane] = AllocRaster(scr->Width, scr->Height);
  743.             if(bitmap->Planes[plane] == NULL)
  744.                 return FALSE;
  745.         }
  746.         /* If we get here, we succeeded. */
  747.         return TRUE;
  748.     }
  749.     else
  750.         return FALSE;
  751. }
  752.  
  753. void freeBitmap()
  754. {
  755.     if(bitmap)
  756.     {
  757.         int plane;
  758.         for(plane = 0; plane < scr->BitMap.Depth; plane++)
  759.         {
  760.             if(bitmap->Planes[plane])
  761.                 FreeRaster(bitmap->Planes[plane], scr->Width, scr->Height);
  762.         }
  763.         FreeMem(bitmap, sizeof(struct BitMap));
  764.         bitmap = NULL;
  765.     }
  766. }
  767.